package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.templates.HuanXinTemplate;
import com.tanhua.domain.db.Question;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.QuestionApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.dubbo.api.mongo.UserLocationApi;
import com.tanhua.server.interceptor.UserHolder;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class TodayBestService {

    @Reference
    private RecommendUserApi recommendUserApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Reference
    private UserLocationApi userLocationApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Reference
    private UserLikeApi userLikeApi;



    /**
     * 查找今日佳人
     * @return
     */
    public ResponseEntity todayBest() {
        //1. 得到当前登陆的用户
        Long userId = UserHolder.getUserId();

        //2. 得到今日佳人的信息 RecommendUser
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if(recommendUser==null){
            recommendUser = recommendUserApi.queryWithMaxScore(1L);
        }
        //3, 创建TodayBestVo对象, 是最终的结果
        TodayBestVo vo = new TodayBestVo();
        //4.封装参数到TodayBestVo对象中
        UserInfo userInfo = userInfoApi.findById(recommendUser.getRecommendUserId());
        //注意：由于我们的数据不完整，有些推荐的用户不存在的用户信息，所以一定要判断。
        if(userInfo!=null){
            BeanUtils.copyProperties(userInfo,vo);
            //设置标签
            if(userInfo.getTags()!=null){
                vo.setTags(userInfo.getTags().split(","));
            }
        }
        //设置缘分值
        vo.setFateValue(recommendUser.getScore().longValue());
        //5. 返回响应 TodayBestVo
        return ResponseEntity.ok(vo);
    }

    /**
     * 查询今日推荐佳人列表
     * @param vo
     * @return
     */
    public ResponseEntity queryRecommendation(RecommendQueryVo vo) {
        //1.得到今日推荐的佳人列表，得到分页对象  pageresult目前里面存储的是RecommendUser
        PageResult pageResult = recommendUserApi.queryRecommendation(vo.getPage(),vo.getPagesize(),UserHolder.getUserId());
        //2.得到pageReuslt的items
        List<RecommendUser> recommendUserList = (List<RecommendUser>) pageResult.getItems();
        //3. 创建TodayBeastVo的List
        List<TodayBestVo> voList = new ArrayList<>();

        //4. 遍历推荐人列表把数据转移到TodayBest的List中
        if(recommendUserList!=null){
            for (RecommendUser recommendUser : recommendUserList) {
                //每一个recommendUser都需要得到TodayBestVo对象
                //, 创建TodayBestVo对象, 是最终的结果
                TodayBestVo todayBestVo = new TodayBestVo();
                //.封装参数到TodayBestVo对象中
                UserInfo userInfo = userInfoApi.findById(recommendUser.getRecommendUserId());
                //注意：由于我们的数据不完整，有些推荐的用户不存在的用户信息，所以一定要判断。
                if(userInfo!=null){
                    BeanUtils.copyProperties(userInfo,todayBestVo);
                    //设置标签
                    if(userInfo.getTags()!=null){
                        todayBestVo.setTags(userInfo.getTags().split(","));
                    }
                }
                //设置缘分值
                todayBestVo.setFateValue(recommendUser.getScore().longValue());
                //把todayBestVo对象添加到集合中
                voList.add(todayBestVo);
            }
        }
        //5. 给Pageresult对象重新设置Items
        pageResult.setItems(voList);

        //6. 把pageResult对象作为相应返回
        return ResponseEntity.ok(pageResult);
    }



    /**
     * 查询佳人信息
     * @param recommendUserId
     * @return
     */
    public ResponseEntity queryPersonalInfo(Long recommendUserId) {
        //1. 查询用户的信息
        UserInfo userInfo = userInfoApi.findById(recommendUserId);
        //2. 创建TodayBestVo
        TodayBestVo todayBestVo = new TodayBestVo();
        //3. userINfo信息封装到TodayBestVo对象中
        if(userInfo!=null){
            BeanUtils.copyProperties(userInfo,todayBestVo);
            //设置标签
            if(userInfo.getTags()!=null){
                todayBestVo.setTags(userInfo.getTags().split(","));
            }
        }
        //设置缘分值
        Long score = recommendUserApi.queryScore(UserHolder.getUserId(),recommendUserId);
        todayBestVo.setFateValue(score);

        //4. 返回即可
        return ResponseEntity.ok(todayBestVo);
    }

    /**
     * 查询推荐用户的陌生人问题
     * @param userId
     * @return
     */
    public ResponseEntity strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        String text = "您多大？";
        if(question!=null){
            text = question.getTxt();
        }
        return ResponseEntity.ok(text);
    }


    /**
     * {"userId":1,"nickname":"黑马小妹","strangerQuestion":"你喜欢去看蔚蓝的大海还是去爬巍峨的高山？",
     * "reply":"我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"}
     */
    /**
     * 回复陌生人问题
     * @param userId  接收人的userId,并不是当前登陆者id
     * @param reply  当前登陆者回复的信息内容
     * @return
     */

    public ResponseEntity replyQuestions(Integer userId, String reply) {
         //1. 查询当前登陆者的用户信息
        UserInfo userInfo = userInfoApi.findById(UserHolder.getUserId());
        //2. 查询对方的问题
        Question question = questionApi.findByUserId(userId.longValue());

        //3.把相关的信息封装到map中
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userInfo.getId());
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",question==null?"您多大？":question.getTxt());
        map.put("reply",reply);
        //4. 发送消息
        String jsonStr = JSON.toJSONString(map);
        huanXinTemplate.sendMsg(userId+"",jsonStr);
        return ResponseEntity.ok(null);

    }

    /**
     * 搜索附近的人
     * @param gender
     * @param distance
     * @return
     */
    public ResponseEntity searchNear(String gender, Long distance) {

        //1. 得到附近人
        Long userId = UserHolder.getUserId();
        //这里的List存储的是UserLocation对象， 请问这里的List是不是调用dubbo的提供者得到的，
        //消费者与提供者如果要传输该对象，那么对象所属的类必须要实现序列化接口。UserLocation不允许通过dubbo传输
        //UserLocation里面有一个属性GeoJsonPoint  属性对象，而这个属性所属的类没有实现序列化接口。
        List<UserLocationVo> userLocationList = userLocationApi.searchNear(userId,distance);

        //2. 创建Volist
        List<NearUserVo> voList = new ArrayList<>();
        //3. 把UserLocationList转移到voList
        if(userLocationList!=null){
            for (UserLocationVo userLocation : userLocationList) {
                UserInfo userInfo = userInfoApi.findById(userLocation.getUserId());
                //过滤性别
                if(!userInfo.getGender().equals(gender) ||userInfo.getId()==userId){
                    continue;//不符合我搜索的性别直接跳过。
                }

                NearUserVo vo = new NearUserVo();
                vo.setUserId(userInfo.getId());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                voList.add(vo);
            }
        }
        return ResponseEntity.ok(voList);
    }

    //探花
    @Scheduled(cron =" 0 0 0 * * ?")
    public ResponseEntity<Object> findTanhua() {
        Long userId = UserHolder.getUserId();
        HashOperations<String, String, String> ops = redisTemplate.opsForHash();
        //放到redis中
        ArrayList<TodayBestVo> tanHuaUser = recommendUserApi.findTanHuaUser(userId);
        for (TodayBestVo todayBestVo : tanHuaUser) {
            TodayBestVo newTodayBestVo = new TodayBestVo();
            BeanUtils.copyProperties(todayBestVo, newTodayBestVo);//两把tag不同
            String jsonUserInfo = JSON.toJSONString(newTodayBestVo);
            ops.put("tanhua_"+userId,todayBestVo.getId().toString(), jsonUserInfo);
            redisTemplate.expire("tanhua_"+userId,24, TimeUnit.HOURS);
        }
        if (redisTemplate.hasKey("tanhua")) {
            //redis 有 就从中获取
            List<String> todayBestVoList = ops.values("tanhua_"+userId);
            tanHuaUser = new ArrayList<>();
            int i = 10;
            for (String list : todayBestVoList) {
                TodayBestVo todayBestVo = JSON.parseObject(list, TodayBestVo.class);
                tanHuaUser.add(todayBestVo);
                i--;
                if (i==0){
                    break;
                }
            }
            return ResponseEntity.ok(tanHuaUser);
        } else {
            return ResponseEntity.ok(tanHuaUser);
        }
    }

    //探花-喜欢
    public ResponseEntity<Object> likeTanHua(Long likeUserId) {
        Long userId = UserHolder.getUserId();
        userLikeApi.addLikeUser(userId,likeUserId);
        //添加成喜欢后，需要在redis中删除
        HashOperations<String, String, String> ops = redisTemplate.opsForHash();
        ops.delete("tanhua"+userId,likeUserId.toString());
        return ResponseEntity.ok(null);
    }

    //探花-不喜欢
    public ResponseEntity<Object> unLikeTanHua(Long unLikeUserId) {
        Long userId = UserHolder.getUserId();
        userLikeApi.addUnLikeUser(userId,unLikeUserId);
        HashOperations<String, String, String> ops = redisTemplate.opsForHash();
        ops.delete("tanhua"+userId,unLikeUserId.toString());
        return ResponseEntity.ok(null);
    }
}
